﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using AdoNet = System.Data;
using System.Globalization;

namespace DataSet4Com
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDispatch)]
    [ComDefaultInterface(typeof(IDataSet))]
    [Guid("EADA743A-3F94-446C-BFDD-F3E38FB2A148")]
    public class DataSet : IDataSet
    {
        private AdoNet.DataSet _adoNetDataSet;

        public DataSet() : this(null)
        { }
                
        public DataSet(AdoNet.DataSet adoNetDataSet)
        {
            if (adoNetDataSet == null)
                _adoNetDataSet = new AdoNet.DataSet();
            else
                _adoNetDataSet = adoNetDataSet;
        }

        [ComVisible(false)]
        public AdoNet.DataSet AdoNetDataSet
        {
            get { return _adoNetDataSet; }
        }

        public bool CaseSensitive 
        {
            get { return _adoNetDataSet.CaseSensitive; }
            set { _adoNetDataSet.CaseSensitive = value; }
        }
        
        public string DataSetName 
        {
            get { return _adoNetDataSet.DataSetName; }
            set { _adoNetDataSet.DataSetName = value; }
        }
        
        //public DataViewManager DefaultViewManager { get; }
        
        public bool EnforceConstraints 
        {
            get { return _adoNetDataSet.EnforceConstraints; }
            set { _adoNetDataSet.EnforceConstraints = value; }
        }
        
        public bool HasErrors 
        {
            get { return _adoNetDataSet.HasErrors; }
        }
        
        public bool IsInitialized 
        {
            get { return _adoNetDataSet.IsInitialized; }
        }
        
        public string Locale 
        {
            get { return _adoNetDataSet.Locale.Name; }
            set { _adoNetDataSet.Locale = CultureInfo.GetCultureInfo(value); }
        }
        
        public string Namespace 
        {
            get { return _adoNetDataSet.Namespace; }
            set { _adoNetDataSet.Namespace = value; }
        }
        
        public string Prefix 
        {
            get { return _adoNetDataSet.Prefix; }
            set { _adoNetDataSet.Prefix = value; }
        }
        
        public DataRelationCollection Relations 
        {
            get { return new DataRelationCollection(_adoNetDataSet.Relations); }
        }
        
        public SerializationFormat RemotingFormat 
        {
            get { return (SerializationFormat)((int)_adoNetDataSet.RemotingFormat); }
            set { _adoNetDataSet.RemotingFormat = (AdoNet.SerializationFormat)((int)_adoNetDataSet.RemotingFormat); }
        }
        
        public DataTableCollection Tables 
        {
            get { return new DataTableCollection(_adoNetDataSet.Tables); }
        }

        public void AcceptChanges()
        {
            _adoNetDataSet.AcceptChanges();
        }

        public void BeginInit()
        {
            _adoNetDataSet.BeginInit();
        }

        public void Clear()
        {
            _adoNetDataSet.Clear();
        }

        public virtual DataSet Clone()
        {
            return new DataSet(_adoNetDataSet.Clone());
        }

        public DataSet Copy()
        {
            return new DataSet(_adoNetDataSet.Copy());
        }

        public void EndInit()
        {
            _adoNetDataSet.EndInit();
        }

        public DataSet GetChanges()
        {
            return new DataSet(_adoNetDataSet.GetChanges());
        }

        public DataSet GetChangesOfRowState(DataRowState rowStates)
        {
            return new DataSet(_adoNetDataSet.GetChanges((AdoNet.DataRowState)((int)rowStates)));
        }

        public bool HasChanges()
        {
            return _adoNetDataSet.HasChanges();
        }

        public bool HasChangesOfRowState(DataRowState rowStates)
        {
            return _adoNetDataSet.HasChanges((AdoNet.DataRowState)((int)rowStates));
        }

        public void MergeRows(DataRowList rows, [Optional, DefaultParameterValue(false)] bool preserveChanges, [Optional, DefaultParameterValue(MissingSchemaAction.AddWithKey)] MissingSchemaAction missingSchemaAction)
        {
            AdoNet.DataRow[] adoNetRows = (from row in rows.InternalList
                                           select row.AdoNetDataRow).ToArray();

            _adoNetDataSet.Merge(adoNetRows, preserveChanges, (AdoNet.MissingSchemaAction)((int)missingSchemaAction));
        }

        public void Merge(DataSet dataSet, [Optional, DefaultParameterValue(false)] bool preserveChanges, [Optional, DefaultParameterValue(MissingSchemaAction.AddWithKey)] MissingSchemaAction missingSchemaAction)
        {
            _adoNetDataSet.Merge(dataSet.AdoNetDataSet, preserveChanges, (AdoNet.MissingSchemaAction)((int)missingSchemaAction));
        }

        public void MergeTable(DataTable table, [Optional, DefaultParameterValue(false)] bool preserveChanges, [Optional, DefaultParameterValue(MissingSchemaAction.AddWithKey)] MissingSchemaAction missingSchemaAction)
        {
            _adoNetDataSet.Merge(table.AdoNetDataTable, preserveChanges, (AdoNet.MissingSchemaAction)((int)missingSchemaAction));
        }

        public virtual void RejectChanges()
        {
            _adoNetDataSet.RejectChanges();
        }

        public virtual void Reset()
        {
            _adoNetDataSet.Reset();
        }
    }

    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    [Guid("D0EF1E86-9024-4C6A-B999-6EC8FC2AE289")]
    public interface IDataSet
    {
        bool CaseSensitive
        {
            get;
            set;
        }

        string DataSetName
        {
            get;
            set;
        }

        //public DataViewManager DefaultViewManager { get; }

        bool EnforceConstraints
        {
            get;
            set;
        }

        bool HasErrors
        {
            get;
        }

        bool IsInitialized
        {
            get;
        }

        string Locale
        {
            get;
            set;
        }

        string Namespace
        {
            get;
            set;
        }

        string Prefix
        {
            get;
            set;
        }

        DataRelationCollection Relations
        {
            get;
        }

        SerializationFormat RemotingFormat
        {
            get;
            set;
        }

        DataTableCollection Tables
        {
            get;
        }

        void AcceptChanges();

        void BeginInit();

        void Clear();

        DataSet Clone();

        DataSet Copy();

        void EndInit();

        DataSet GetChanges();

        DataSet GetChangesOfRowState(DataRowState rowStates);

        bool HasChanges();

        bool HasChangesOfRowState(DataRowState rowStates);

        void MergeRows(DataRowList rows, [Optional, DefaultParameterValue(false)] bool preserveChanges, [Optional, DefaultParameterValue(MissingSchemaAction.AddWithKey)] MissingSchemaAction missingSchemaAction);

        void Merge(DataSet dataSet, [Optional, DefaultParameterValue(false)] bool preserveChanges, [Optional, DefaultParameterValue(MissingSchemaAction.AddWithKey)] MissingSchemaAction missingSchemaAction);

        void MergeTable(DataTable table, [Optional, DefaultParameterValue(false)] bool preserveChanges, [Optional, DefaultParameterValue(MissingSchemaAction.AddWithKey)] MissingSchemaAction missingSchemaAction);

        void RejectChanges();

        void Reset();
    }
}
